#include "cmd.hpp"
#include "db_manager.hpp"
#include <sstream>
#include <mysql/mysql.h>
#include <vector>
#include <iostream>

std::vector<Cmd> Cmd::getAll() {
    std::vector<Cmd> cmds;
    auto* mysql = DBManager::getInstance().getConnection();
    
    const char* query = "SELECT id, cmdid, content FROM CmdIDConfig";
    if (mysql_query(mysql, query)) {
        std::cerr << "Cmd::getAll - MySQL query error: " << mysql_error(mysql) << std::endl;
        return cmds;
    }
    
    MYSQL_RES* result = mysql_store_result(mysql);
    if (!result) {
        return cmds;
    }
    
    MYSQL_ROW row;
    while ((row = mysql_fetch_row(result))) {
        Cmd cmd;
        cmd.id = std::stoi(row[0]);
        cmd.cmdid = std::stoi(row[1]);
        cmd.content = row[2] ? row[2] : "";
        cmds.push_back(cmd);
    }
    
    mysql_free_result(result);
    return cmds;
}

Cmd Cmd::getById(int id) {
    Cmd cmd;
    auto* mysql = DBManager::getInstance().getConnection();
    
    std::stringstream ss;
    ss << "SELECT id, cmdid, content FROM CmdIDConfig WHERE id = " << id;
    
    if (mysql_query(mysql, ss.str().c_str())) {
        std::cerr << "Cmd::getById - MySQL query error: " << mysql_error(mysql) << std::endl;
        return cmd;
    }
    
    MYSQL_RES* result = mysql_store_result(mysql);
    if (!result) {
        return cmd;
    }
    
    MYSQL_ROW row = mysql_fetch_row(result);
    if (row) {
        cmd.id = std::stoi(row[0]);
        cmd.cmdid = std::stoi(row[1]);
        cmd.content = row[2] ? row[2] : "";
    }
    
    mysql_free_result(result);
    return cmd;
}

bool Cmd::add(int cmdid, const std::string& content) {
    auto* mysql = DBManager::getInstance().getConnection();
    if (!mysql) {
        std::cerr << "Cmd::add - Failed to get DB connection" << std::endl;
        return false;
    }

    std::vector<char> escaped_content_buffer(content.length() * 2 + 1);
    unsigned long escaped_length = mysql_real_escape_string(mysql, 
                                                             escaped_content_buffer.data(), 
                                                             content.c_str(), 
                                                             content.length());

    std::stringstream ss;
    ss << "INSERT INTO CmdIDConfig (cmdid, content) VALUES ("
       << cmdid << ", '" 
       << std::string(escaped_content_buffer.data(), escaped_length)
       << "')";
    
    if (mysql_query(mysql, ss.str().c_str()) != 0) {
        std::cerr << "Cmd::add - MySQL query error: " << mysql_error(mysql) << std::endl;
        std::cerr << "Failing query: " << ss.str() << std::endl;
        return false;
    }
    
    return true;
}

bool Cmd::update(int id, const std::string& content) {
    auto* mysql = DBManager::getInstance().getConnection();
    if (!mysql) {
        std::cerr << "Cmd::update - Failed to get DB connection" << std::endl;
        return false;
    }

    std::vector<char> escaped_content_buffer(content.length() * 2 + 1);
    unsigned long escaped_length = mysql_real_escape_string(mysql, 
                                                             escaped_content_buffer.data(), 
                                                             content.c_str(), 
                                                             content.length());

    std::stringstream ss;
    ss << "UPDATE CmdIDConfig SET content = '"
       << std::string(escaped_content_buffer.data(), escaped_length)
       << "' WHERE id = " << id;
    
    if (mysql_query(mysql, ss.str().c_str()) != 0) {
        std::cerr << "Cmd::update - MySQL query error: " << mysql_error(mysql) << std::endl;
        std::cerr << "Failing query: " << ss.str() << std::endl;
        return false;
    }

    return true;
}

bool Cmd::remove(int id) {
    auto* mysql = DBManager::getInstance().getConnection();
    
    std::stringstream ss;
    ss << "DELETE FROM CmdIDConfig WHERE id = " << id;
    
    if (mysql_query(mysql, ss.str().c_str()) != 0) {
        std::cerr << "Cmd::remove - MySQL query error: " << mysql_error(mysql) << std::endl;
        std::cerr << "Failing query: " << ss.str() << std::endl;
        return false;
    }
    return true;
}

bool Cmd::exists(int cmdid) {
    auto* mysql = DBManager::getInstance().getConnection();
    std::stringstream ss;
    ss << "SELECT COUNT(*) FROM CmdIDConfig WHERE cmdid = " << cmdid;
    if (mysql_query(mysql, ss.str().c_str())) {
        return false;
    }
    MYSQL_RES* result = mysql_store_result(mysql);
    if (!result) {
        return false;
    }
    MYSQL_ROW row = mysql_fetch_row(result);
    bool found = false;
    if (row && row[0]) {
        found = (std::stoi(row[0]) > 0);
    }
    mysql_free_result(result);
    return found;
} 